package com.yyf.blogapi.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yyf.blogapi.po.*;
import com.yyf.blogapi.mapper.ArticleMapper;
import com.yyf.blogapi.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yyf.blogapi.util.DateUtil;
import com.yyf.blogapi.util.UserThreadLocal;
import com.yyf.blogapi.vo.Archives;
import com.yyf.blogapi.vo.ArticleVo;
import com.yyf.blogapi.vo.PageParams;
import com.yyf.blogapi.vo.TagVo;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yyf
 * @since 2021-08-16
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements IArticleService {

    @Resource
    private ArticleMapper articleMapper;
    @Resource
    private ITagService tagService;
    @Resource
    private ISysUserService sysUserService;
    @Resource
    private IArticleBodyService articleBodyService;
    @Resource
    ICategoryService categoryService;
    @Resource
    UpdateViewCountService updateViewCountService;
    @Resource
    IArticleTagService articleTagService;
    @Resource
    ICommentService commentService;

    @Override
    public List<ArticleVo> listArticle(PageParams pageParams) {
        Page<Article> articlePage = new Page<>(pageParams.getPage(), pageParams.getPageSize());
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        //首先看是否置顶
        //再按时间倒序排序
        queryWrapper.orderByDesc(Article::getWeight, Article::getCreateDate);
        //参数中若是有categoryId，则按照分类id查询
        if (pageParams.getCategoryId() != null) {
            queryWrapper.eq(Article::getCategoryId, pageParams.getCategoryId());
        }
        //参数中若是有tagId
        if (pageParams.getTagId() != null) {
            List<Long> articleIds = articleTagService.getArticleIdByTagId(pageParams.getTagId());
            if (CollectionUtils.isNotEmpty(articleIds)) {
                queryWrapper.in(Article::getId, articleIds);
            }
        }
        if (pageParams.getYear() != null && pageParams.getMonth() != null) {
            String beforeMonth = String.valueOf(Integer.parseInt(pageParams.getMonth()) - 1);
            String nextMonth = String.valueOf(Integer.parseInt(pageParams.getMonth()) + 1);
            queryWrapper.between(Article::getCreateDate,
                    DateUtil.getMillisFromyyyyMM(pageParams.getYear(),beforeMonth),
                    DateUtil.getMillisFromyyyyMM(pageParams.getYear(),nextMonth));
        }
        Page<Article> selectPage = articleMapper.selectPage(articlePage, queryWrapper);
        List<Article> records = selectPage.getRecords();
        return copyList(records);

    }

    @Override
    public List<Article> hotArticle(int limit) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Article::getViewCounts).select(Article::getId, Article::getTitle).last("limit " + limit);
        return articleMapper.selectList(queryWrapper);
    }

    @Override
    public List<Article> newArticle(int limit) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Article::getCreateDate).select(Article::getId, Article::getTitle).last("limit " + limit);
        return articleMapper.selectList(queryWrapper);
    }

    @Override
    public List<Archives> listArchives() {
        return articleMapper.listArchives();
    }

    @Override
    public ArticleVo getArticleById(Long id) {
        Article article = articleMapper.selectById(id);
        int commentsCount = commentService.commentsCount(id);
        article.setCommentCounts(commentsCount);
        updateViewCountService.updateViewCount(articleMapper, article);
        return copy(article, true, true, true, true);
    }

    @Override
    public Map<String, String> publish(ArticleVo articleVo) {
        SysUser user = UserThreadLocal.get();
        Article article = new Article();
        article.setTitle(articleVo.getTitle());
        article.setSummary(articleVo.getSummary());
        article.setAuthorId(user.getId());
        article.setCategoryId(articleVo.getCategory().getId());
        article.setCommentCounts(0);
        article.setViewCounts(0);
        article.setWeight(0);
        article.setCreateDate(System.currentTimeMillis());
        articleMapper.insert(article);

        Long articleId = article.getId();

        //body
        ArticleBody articleBody = new ArticleBody();
        articleBody.setContent(articleVo.getBody().getContent());
        articleBody.setContentHtml(articleVo.getBody().getContentHtml());
        articleBody.setArticleId(articleId);
        articleBodyService.save(articleBody);
        article.setBodyId(articleBody.getId());
        articleMapper.updateById(article);

        //tags
        List<TagVo> tags = articleVo.getTags();
        if (CollectionUtils.isNotEmpty(tags)) {
            for (TagVo tag : tags) {
                ArticleTag articleTag = new ArticleTag();
                articleTag.setArticleId(articleId);
                articleTag.setTagId(tag.getId());
                articleTagService.save(articleTag);
            }
        }

        Map<String, String> data = new HashMap<>();
        data.put("id", article.getId().toString());
        return data;
    }

    public List<ArticleVo> copyList(List<Article> records) {
        ArrayList<ArticleVo> listArticleVo = new ArrayList<>();
        for (Article record : records) {
            listArticleVo.add(copy(record, true, true));
        }
        return listArticleVo;
    }

    private ArticleVo copy(Article article, boolean isTag, boolean isAuthor) {
        ArticleVo articleVo = new ArticleVo();
        BeanUtils.copyProperties(article, articleVo);
        articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-MM-dd HH:mm"));
        if (isTag) {
            Long articleId = article.getId();
            articleVo.setTags(tagService.getTagsByArticleId(articleId));
        }
        if (isAuthor) {
            Long authorId = article.getAuthorId();
            articleVo.setAuthor(sysUserService.getById(authorId).getNickname());
        }
        return articleVo;
    }


    private ArticleVo copy(Article article, boolean isTag, boolean isAuthor, boolean isBody, boolean isCategory) {
        ArticleVo articleVo = new ArticleVo();
        BeanUtils.copyProperties(article, articleVo);
        articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-MM-dd HH:mm"));
        if (isTag) {
            Long articleId = article.getId();
            articleVo.setTags(tagService.getTagsByArticleId(articleId));
        }
        if (isAuthor) {
            Long authorId = article.getAuthorId();
            articleVo.setAuthor(sysUserService.getById(authorId).getNickname());
        }
        if (isBody) {
            Long bodyId = article.getBodyId();
            articleVo.setBody(articleBodyService.getArticleBodyById(bodyId));

        }
        if (isCategory) {
            Long categoryId = article.getCategoryId();
            articleVo.setCategory(categoryService.getById(categoryId));
        }
        return articleVo;
    }
}
